--
-- Author: shunguo.chen
-- Date: 2017-01-10 11:07:46
--
-- PlayerModel

local Equip = require("app.public.dao.Equip")
local PlayerOtherUser = import(".PlayerOtherUser")

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ModelBase)

-- local OBSERVE_GAP_MIN = 3
-- local OBSERVE_GAP_MAX = 200

local MENU_BASE_NAMES = {
    attr = L("function_name_attr"),
    set = L("function_name_set"),
    observe = L("observe_viewplayer"),
    mercenary = L("function_name_mercenary"),
    friend = L("observe_addfriend"),
    delFriend = L("lua_code_text_8"),
    black = L("observe_addblacklist"),
    mail = L("observe_mail"),
    chat = L("observe_privatechat"),
    switchUser = L("lua_code_text_431"),
    achive = L("lua_code_text_237"),
    friendView = L("friend"),
    captainRoom = L("lua_code_text_401"),
    visitCaptainRoom = L("lua_code_text_322"),
    report = L("reportPlayer"),

    kickPartner = L("lua_code_text_321"),
    changePartner = L("lua_code_text_100"),

    kickRobot = L("text_10500039"), -- 踢掉机器人

    guildOfficer = L("guildOfficerString"),  --任命精英
    guildUnOfficer = L("guildUnOfficerString"),  --取消精英
    guildLeader = L("guildLeaderString"),  --转让会长
    guildDisband = L("guildDisbandString"),  --解散公会
    guildKick = L("guildKickString"),  --踢出公会
    guildQuit = L("guildQuitString"),  --退出公会
    guildInvite = L("guildInviteString"),  --邀请入会
    guildPeerageChange = L("guildPeerageChangeString"), --调整职位
    guildInfo = L("SuperRankDetails"),

    
    duelKickPartner = L("lua_code_text_321"),
    duelChoosePartner = L("lua_code_text_100"),

    eliteDuelKickPartner = L("lua_code_text_321"),
    eliteDuelChoosePartner = L("lua_code_text_100"),
}

local MENU_TEAM_NAMES = {
    teamInvite = L("observe_team"),
    teamJoin = L("observe_join"),
    teamLeave = L("text_10500036"),
    teamBack = L("returnteam"),
    teamQuit = L("text_10500037"),
    teamKick = L("text_10500039"),
    teamLeader = L("text_10500040"),
    teamSwitch = L("tips_3000123"),
    teamReady = L("tips_3000172"),
    teamImpeach = L("lua_code_text_151"),
}

local MENU_LEGION_NAMES = {
    teamInvite = L("tips_3000165"),
    teamJoin = L("observe_join"),
    teamLeave = L("tips_3000169"),
    teamBack = L("tips_3000132"),
    teamQuit = L("tips_3000156"),
    teamKick = L("tips_3000154"),
    teamLeader = L("tips_3000175"),
    teamSwitch = L("lua_code_text_525"),
    teamReady = L("tips_3000172"),
    teamImpeach = L("lua_code_text_106"),
}

function ClassRef:ctor(data)
	self.super.ctor(self, data)
end

function ClassRef:init()
	self._teamModel = app:getInst("TeamModel")

    -- 观察者信息
    self._observeDict = {}
end

function ClassRef:getMenuName(key)
    local ret = MENU_BASE_NAMES[key]
    if not ret then
        if self._teamModel:isLegion() then
            ret = MENU_LEGION_NAMES[key]
        else
            ret = MENU_TEAM_NAMES[key]
        end
    end
    return ret or ""
end



-- message S2C_WorldExpLock {
--     int32 lockId = 1;//经验锁id
--     int32 lockLevel = 2;//经验锁等级
--     int64 unlockTime = 3;//解锁时间戳
--     int32 expPool = 4;//经验池经验
-- }
-- 获取经验锁
function ClassRef:C2S_WorldExpLock(cb)
    app.session:request("pb_server.C2S_WorldExpLock",{},function(msg)
        executeFunc(cb, msg)
    end)
end

-- 帮助函数：邀请入会（公会）是否出现在菜单中
-- ret = table 传引用
function ClassRef:canBeInvitedToGuild( ret )
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_GANG) then -- 功能开放？
        if UD:isInGuild() then -- 我有工会？
            local keyTemp = Enums.MenuItems.guildInvite
            local temp = {}
            temp.key = keyTemp
            temp.name = self:getMenuName( keyTemp )
            ret[#ret+1] = temp
        end
    end
end



-- 添加举报功能到菜单中
function ClassRef:addReportToMenu(ret)
    local keyTemp = Enums.MenuItems.report
    local temp = {}
    temp.key = keyTemp
    temp.name = self:getMenuName(keyTemp)
    ret[#ret+1] = temp
end

function ClassRef:getPlayerMenuList(uid)
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.observe}
    ret[#ret + 1] = {key=Enums.MenuItems.visitCaptainRoom}

    -- 组队功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CREATE_TEAM) then
        -- 不在一个队伍添加 邀请入队
        if not self._teamModel:isInTeam(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.teamInvite}
            ret[#ret+1] = {key=Enums.MenuItems.teamJoin}
        else -- 在一个小队中
            if self._teamModel:isLeader( UD.player.uid ) then -- 并且我是队长/团长
                ret[#ret+1] = {key=Enums.MenuItems.teamLeader}
                if self._teamModel:isTeamNormal() then -- 正常状态？
                    ret[#ret+1] = {key=Enums.MenuItems.teamKick}
                end
            end
        end

        if self._teamModel:isLeader(uid) then  -- uid是队长/团长，队员可以弹劾他
            ret[#ret+1] = {key = Enums.MenuItems.teamImpeach}
        end
    end

    -- 好友功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_FRIEND) then
        --不是好友添加 邀请好友
        if not UD:isFriend(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.friend}
        end

        --不是黑名单 添加黑名单
        if not UD:isBlack(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.black}
        end
    end

    

    -- 聊天功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CHAT) then
        ret[#ret+1] = {key=Enums.MenuItems.chat}
    end

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    -- dump(ret, "PlayerModel.getPlayerMenuList uid=" .. uid)
    return ret
end

function ClassRef:getCaptainRoomMenuList(uid, hideCaptain)
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.observe}
    if not hideCaptain then
        ret[#ret + 1] = {key=Enums.MenuItems.visitCaptainRoom}
    end

    -- 好友功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_FRIEND) then
        --不是好友添加 邀请好友
        if not UD:isFriend(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.friend}
        end

        --不是黑名单 添加黑名单
        if not UD:isBlack(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.black}
        end
    end

    -- 组队功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CREATE_TEAM) then
        -- 不在一个队伍添加 邀请入队
        if not self._teamModel:isInTeam(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.teamInvite}
            ret[#ret+1] = {key=Enums.MenuItems.teamJoin}
        else -- 在一个小队中
            if self._teamModel:isLeader( UD.player.uid ) then -- 并且我是队长/团长
                ret[#ret+1] = {key=Enums.MenuItems.teamLeader}
                if self._teamModel:isTeamNormal() then -- 正常状态？
                    ret[#ret+1] = {key=Enums.MenuItems.teamKick}
                end
            end
        end
    end

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    return ret
end

function ClassRef:getHeadMenuList()
    local ret = {}
    -- ret[#ret+1] = {key=Enums.MenuItems.achive}
    ret[#ret+1] = {key=Enums.MenuItems.captainRoom, showRedPoint=app:sendMsg("CaptainModelRedPoint", "captainRoomHasRedPoint")}
    ret[#ret+1] = {key=Enums.MenuItems.friendView}
    ret[#ret+1] = {key=Enums.MenuItems.achive}
    ret[#ret+1] = {key=Enums.MenuItems.set}
    ret[#ret+1] = {key=Enums.MenuItems.switchUser}

    -- 组队功能开启
    -- if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CREATE_TEAM) then
    --     -- 在队伍中才有各种操作
    --     if self._teamModel:isInTeam() then
    --         ret[#ret+1] = {key=Enums.MenuItems.teamQuit}
    --         if self._teamModel:isLeader() then
    --             -- 我是队长
    --             ret[#ret+1] = {key=Enums.MenuItems.teamSwitch}
    --             ret[#ret+1] = {key=Enums.MenuItems.teamReady}
    --         else
    --             -- 我是队员
    --             if self._teamModel:isAwayFromTeam() then
    --                 -- 暂离
    --                 ret[#ret+1] = {key=Enums.MenuItems.teamBack}
    --             else
    --                 ret[#ret+1] = {key=Enums.MenuItems.teamLeave}
    --             end
    --         end
    --     end
    -- end

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    -- dump(ret, "PlayerModel.getHeadMenuList")
    return ret
end

-- 好友界面的menu
function ClassRef:getFriendMenuList(uid)
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.observe}

    local friendType
    if UD:isFriend(uid) then
        friendType = Enums.FriendType.friend
    elseif UD:isBlack(uid) then
        friendType = Enums.FriendType.black
    else
        friendType = Enums.FriendType.stranger
    end

    -- 好友功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_FRIEND) then
        if friendType ~= Enums.FriendType.black then
            ret[#ret+1] = {key=Enums.MenuItems.black}
        end
        if friendType == Enums.FriendType.friend then
            ret[#ret+1] = {key=Enums.MenuItems.delFriend}
        end
    end

    -- 组队功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CREATE_TEAM) then
        local isSameTeam = self._teamModel:isInTeam(uid)
        local isLeader = self._teamModel:isLeader(UD.player.uid)
        if not isSameTeam then
            if friendType == Enums.FriendType.black then
                ret[#ret+1] = {key=Enums.MenuItems.teamInvite}
            end
            ret[#ret+1] = {key=Enums.MenuItems.teamJoin}
        elseif isLeader then
            ret[#ret+1] = {key=Enums.MenuItems.teamLeader}
            if self._teamModel:isTeamNormal() then -- 正常状态？
                ret[#ret+1] = {key=Enums.MenuItems.teamKick}
            end
        end
    end

    -- 聊天功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CHAT) then
        if friendType ~= Enums.FriendType.friend then
            ret[#ret+1] = {key=Enums.MenuItems.chat}
        end
    end
    ret[#ret + 1] = {key=Enums.MenuItems.visitCaptainRoom}

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    -- dump(ret, "PlayerModel.getFriendMenuList uid=" .. uid)
    return ret
end

-- 返回随从操作菜单
function ClassRef:getTeamPartnerMenuList()
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.kickPartner}
    ret[#ret+1] = {key=Enums.MenuItems.changePartner}

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    return ret
end

-- 返回队伍机器人操作菜单
function ClassRef:getTeamRobotMenuList()
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.kickRobot}

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    return ret
end

--决斗赛弹窗 踢出随从 和 切换随从
function ClassRef:getDuelMenuList()
 local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.duelKickPartner}
    ret[#ret+1] = {key=Enums.MenuItems.duelChoosePartner}
    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end

    return ret
end

-- 精英决斗赛弹窗 踢出随从 和 切换随从
function ClassRef:getEliteDuelMenuList()
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.eliteDuelKickPartner}
    ret[#ret+1] = {key=Enums.MenuItems.eliteDuelChoosePartner}
    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end
    return ret
end

-- 返回公会成员操作菜单
function ClassRef:getGuildMemberMenuList( data )
    local ret = {}

    local guildMmeberVo = data.attr -- 操作对象
    if guildMmeberVo:isMe() then -- 操作对象是自己？
        if guildMmeberVo:isGuildLeader() then -- 操作对象是会长？
            ret[#ret+1] = {key=Enums.MenuItems.guildDisband}
        else
            ret[#ret+1] = {key=Enums.MenuItems.guildQuit}
        end
        ret[#ret + 1] = {key=Enums.MenuItems.visitCaptainRoom}
    else
        ret[#ret+1] = {key=Enums.MenuItems.observe}
        ret[#ret + 1] = {key=Enums.MenuItems.visitCaptainRoom}
        -- 好友功能开启
        if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_FRIEND) then
            --不是好友添加 邀请好友
            if not UD:isFriend( guildMmeberVo:getMemberId() ) then
                ret[#ret+1] = {key=Enums.MenuItems.friend}
            end
        end
        local guildModel = app:getInst("NewguildModel")


        if guildModel:isGuildLeader() then -- 如果我是会长
            if guildModel:getMaxActiveTerritoryId() > 0 then
                ret[#ret+1] = {key=Enums.MenuItems.guildPeerageChange}
            else
                if guildMmeberVo:isGuildOfficer() then -- 操作对象是精英
                    ret[#ret+1] = {key=Enums.MenuItems.guildUnOfficer}
                else
                    ret[#ret+1] = {key=Enums.MenuItems.guildOfficer}
                end
            end

            ret[#ret+1] = {key=Enums.MenuItems.guildLeader}
            ret[#ret+1] = {key=Enums.MenuItems.guildKick}
        elseif guildModel:isGuildManager() then
            --若目标不是工会的管理者
            local myMemberVo = guildModel:getMyGuildMemberInfo()
            if guildMmeberVo:isNormalMember() or ( (not guildMmeberVo:isGuildLeader()) and (myMemberVo:getTitleId() >  guildMmeberVo:getTitleId())) then
                if guildModel:getMaxActiveTerritoryId() > 0 then
                    ret[#ret+1] = {key=Enums.MenuItems.guildPeerageChange}
                end
                ret[#ret+1] = {key=Enums.MenuItems.guildKick}
            end
        end

            -- 组队功能开启
        if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_CREATE_TEAM) then
            local isSameTeam = self._teamModel:isInTeam(guildMmeberVo:getMemberId())
            local isLeader = self._teamModel:isLeader(UD.player.uid)
            if not isSameTeam then
                ret[#ret+1] = {key=Enums.MenuItems.teamInvite}
                ret[#ret+1] = {key=Enums.MenuItems.teamJoin}
            elseif isLeader then
                ret[#ret+1] = {key=Enums.MenuItems.teamLeader}
                if self._teamModel:isTeamNormal() then -- 正常状态？
                    ret[#ret+1] = {key=Enums.MenuItems.teamKick}
                end
            end
        end
        ret[#ret+1] = {key=Enums.MenuItems.report}
    end
    
    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end
    return ret
end

function ClassRef:getChessMenuList(data)
    local ret = {}
    ret[#ret+1] = {key=Enums.MenuItems.chat}

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end
    return ret
end


function ClassRef:getObServeAndGuildMenuList(data)
    local ret = {}
    
    if data.userInfo then
        ret[#ret+1] = {key=Enums.MenuItems.observe}
    end
    if  data.guildInfo then
        ret[#ret+1] = {key=Enums.MenuItems.guildInfo}
    end

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end
    return ret
end


function ClassRef:getChampionMenuList(uid)
    local ret = {}
    ret[#ret + 1] = {key=Enums.MenuItems.observe}

    -- 好友功能开启
    if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_FRIEND) then
        --不是好友添加 邀请好友
        if not UD:isFriend(uid) then
            ret[#ret+1] = {key=Enums.MenuItems.friend}
        end

        --不是黑名单 添加黑名单
        if not UD:isBlack(uid) then
            -- 冠军赛队友不显示黑名单
            local throneTeam = app:getInst("PvpModel"):getThroneTeam()
            if throneTeam and throneTeam:isMyTeamMember(uid) then
                -- do nothing
            else
                ret[#ret+1] = {key=Enums.MenuItems.black}
            end
        end
    end
    ret[#ret+1] = {key=Enums.MenuItems.chat}

    for i,v in ipairs(ret) do
        v.name = self:getMenuName(v.key)
    end
    return ret
end

function ClassRef:getMenuList(data)
    local ret = {}
    if data.type == Enums.MenuType.player then
        ret = self:getPlayerMenuList(data.attr.uid)
        self:canBeInvitedToGuild( ret )
        self:addReportToMenu(ret)
    elseif data.type == Enums.MenuType.head then
        ret = self:getHeadMenuList()
    elseif data.type == Enums.MenuType.friend then
        ret = self:getFriendMenuList(data.attr.uid)
        self:canBeInvitedToGuild( ret )
        self:addReportToMenu(ret)
    elseif data.type == Enums.MenuType.teamPartner then
        ret = self:getTeamPartnerMenuList()
    elseif data.type == Enums.MenuType.teamRobot then
        ret = self:getTeamRobotMenuList()
    elseif data.type == Enums.MenuType.guildMember then
        ret = self:getGuildMemberMenuList( data )
    elseif data.type == Enums.MenuType.duel then
        ret = self:getDuelMenuList() 
    elseif data.type == Enums.MenuType.chess then
        ret = self:getChessMenuList( data )
    elseif data.type == Enums.MenuType.champion then
        ret = self:getChampionMenuList( data.attr.uid )
        self:addReportToMenu(ret)
    elseif data.type == Enums.MenuType.visitCaptainRoom then
        ret = self:getCaptainRoomMenuList( data.attr.uid , data.attr.hideCaptain)
        self:canBeInvitedToGuild( ret )
        self:addReportToMenu(ret)
    elseif data.type == Enums.MenuType.eliteDuel then
        ret = self:getEliteDuelMenuList()
    elseif data.type == Enums.MenuType.observeAndGuild then
        ret = self:getObServeAndGuildMenuList(data)
    end

    return ret
end

function ClassRef:getLvUpShowData(lv)
    local player = UD.player

    local baseConf = player:getBaseConf()
    local attrNames = player:getBaseAttrNames()

    local attrs = {}
    for i,name in ipairs(attrNames) do
        local attr = {}
        local base = tonumber(baseConf[name] or 0)
        local lvup = tonumber(baseConf[name.."lv"] or 0)
        lvup = lvup / 100
        attr.name = L(name)
        attr.old = math.floor(base + lvup * (lv - 2))
        attr.new = math.floor(base + lvup * (lv - 1))
        attrs[i] = attr
    end

    local lvConf = GD:queryHeroLevelUpByLevel(lv - 1)
    local items = {}
    local dropIds = string.split(lvConf.drop, ";")
    for _,id in ipairs(dropIds) do
        items[#items+1] = UD:parseDropToBagItem(UD:parseClassText(id, player.classID), true)
    end

    return lv, attrs, items
end

function ClassRef:getInitExpData()
    local level = UD:getLevel()
    local conf = GD:queryHeroLevelUpByLevel(level)
    local maxExp = tonumber(conf.exp)

    return {level = level, exp = UD:getExp(), maxExp = maxExp, poolExp = UD:getExpPool()}
end

function ClassRef:getExpStepDatas(curData, addExp)
    local level = curData.level
    local exp = curData.exp
    local maxExp = curData.maxExp

    local maxLevel = tonumber(S("maxlvforpro", 60))

    local rets = {curData}
    exp = exp + addExp

    while true do
        if level < maxLevel then
            if exp < maxExp then
                local ret = {level=level, exp=exp, maxExp=maxExp}
                rets[#rets + 1] = ret
                break
            else
                local ret = {level=level, exp=maxExp, maxExp=maxExp}
                rets[#rets + 1] = ret

                level = level + 1
                local conf = GD:queryHeroLevelUpByLevel(level)
                exp = exp - maxExp
                maxExp = tonumber(conf.exp)
            end
        else
            local ret = {level=level, exp=exp, maxExp=maxExp}
            rets[#rets + 1] = ret
            break
        end
    end

    return rets
end


---------------------------------------- server --------------------------------------
-- 有人偷窥
function ClassRef:someoneObserveMe(ret)
    local pre = self._observeDict[ret.uid]
    local curTime = os.time()
    if pre then
        if curTime - pre.time <= 30 then
            return
        end
    else
        pre = {}
        self._observeDict[ret.uid] = pre
    end

    pre.time = curTime
    local logStr = L("lua_code_text_395")

    local textAry = {"[u|", ret.name, "|", ret.uid, "]"}
    local nameStr = table.concat(textAry, "")
    app:sendMsg("IMModel", "addSystemMsg", logStr, nameStr)
end

----------------------------------------- request -----------------------------------
function ClassRef:reqWatchOtherUser(uid)
    if not uid or uid <= 0 then return end 
    app.session:request("pb_query.C2S_QueryOtherUser", {uid = uid}, function(ret)
        local userInfo = PlayerOtherUser.new(ret)
        app:sendMsg("OtherPlayerController", "openView", userInfo)
    end)
end

function ClassRef:reqOtherBaseInfo(uid, cb)
    app.session:request("pb_query.C2S_QueryOtherUser", {uid = uid}, function(ret)
        local info = UserBaseInfo.new(ret.baseinfo)
        local userInfo = PlayerOtherUser.new(ret)
        executeFunc(cb, info, userInfo)
    end)
end

function ClassRef:reqSecReport(data)
    if not data then return end
    -- dump(data, "PlayerModel reqSecReport")
    app.session:request("pb_query.C2S_SecReport", data, function(ret)
        display.pushToast(L("report_success"))
        app:sendMsg("ReportController", "closeView")
    end)
end

return ClassRef
